<template>
  <div class="tag-container">
    <el-tag
      v-bind="$attrs"
      v-for="tag in localTags"
      :key="tag.text"
      :type="tag.color"
      size="default"
      @close="handleClose(tag.text)"
    >
      {{ tag.text }}
    </el-tag>
    <div v-if="editable">
      <el-input
        v-if="inputVisible"
        ref="inputRef"
        v-model="inputValue"
        class="w-20"
        size="small"
        @keyup.enter="handleInputConfirm"
        @blur="handleInputConfirm"
      />
      <el-button v-else size="small" @click="showInput"> + 添加标签 </el-button>
    </div>
  </div>
</template>

<script setup name="YTag">
const emit = defineEmits(["update:modelValue"]);
const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  editable: { type: Boolean, default: true },
});

const inputValue = ref("");
const inputVisible = ref(false);
const inputRef = ref();
const tagColors = ref({});

/** 随机设置Tag element风格样式 */
const randomType = () => {
  const types = ["primary", "success", "info", "warning", "danger"];
  return types[Math.floor(Math.random() * types.length)];
};

/** 创建响应式副本，初始化localTags，为每个标签添加text和color属性 */
const localTags = ref(
  props.modelValue.map((tag) => ({
    text: tag,
    color: tagColors.value[tag] || (tagColors.value[tag] = randomType()),
  }))
);

/** 监听 props.modelValue 的变化，以便更新 localTags */
watch(
  () => props.modelValue,
  (newTags) => {
    localTags.value = newTags.map((tag) => ({
      text: tag,
      color: tagColors.value[tag] || (tagColors.value[tag] = randomType()),
    }));
  },
  {
    // 组件创建时立即执行
    immediate: true,
    // 深度监听对象数组
    deep: true,
  }
);

/** 关闭标签方法 */
const handleClose = (text) => {
  const index = localTags.value.findIndex((tag) => tag.text === text);
  if (index !== -1) {
    localTags.value.splice(index, 1);
    // 向父组件发送纯文本数组
    emit(
      "update:modelValue",
      localTags.value.map((tag) => tag.text)
    );
    delete tagColors.value[text];
  }
};

/** 打开输入框方法 */
const showInput = () => {
  inputVisible.value = true;
  nextTick(() => {
    inputRef.value.input.focus();
  });
};

/** 确认输入结果方法 */
const handleInputConfirm = () => {
  if (
    inputValue.value &&
    !localTags.value.some((tag) => tag.text === inputValue.value)
  ) {
    localTags.value.push({
      text: inputValue.value,
      color:
        tagColors.value[inputValue.value] ||
        (tagColors.value[inputValue.value] = randomType()),
    });
    // 向父组件发送纯文本数组
    emit(
      "update:modelValue",
      localTags.value.map((tag) => tag.text)
    );
  }
  inputVisible.value = false;
  inputValue.value = "";
};
</script>

<style scoped>
.tag-container {
  display: flex; /* 使用flex布局使元素水平排列 */
  flex-wrap: wrap; /* 允许内容自动换行 */
  align-items: center; /* 垂直居中 */
  grid-gap: 0.5rem;
  gap: 0.5rem; /* 设置元素之间的间隔 */
}
.tag {
  /* 添加标签的样式 */
  padding: 5px 10px;
  background-color: #f0f0f0;
  border-radius: 5px;
  margin-right: 5px; /* 设置额外的间隔 */
}
</style>
